package com.hucc.api.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hucc.api.domain.entity.Group;
import com.hucc.api.domain.entity.Interface;
import com.hucc.api.domain.entity.InterfaceWithBLOBs;
import com.hucc.api.domain.entity.Project;
import com.hucc.api.domain.exceptions.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class OpenApiService {
    @Autowired
    ProjectService projectService;

    @Autowired
    GroupService groupService;
    @Autowired
    InterfaceService interfaceService;


    public void collectSwaggerDoc(String doc) throws BusinessException {
        log.info("collectSwaggerDoc: {}", doc);
        if (StringUtils.isEmpty(doc)) {
            throw new BusinessException("Swagger文档为空");
        }

        JSONObject jsonObject = JSON.parseObject(doc);
        String swagger = jsonObject.getString("swagger");
        if (!"2.0".equals(swagger)) {
            throw new BusinessException("Swagger文档版本不支持，请使用Swagger 2.0");
        }

        JSONObject info = jsonObject.getJSONObject("info");
        if (info == null) {
            throw new BusinessException("Swagger文档中缺少info字段");
        }
        String version = info.getString("version");
        if (StringUtils.isEmpty(version)) {
            throw new BusinessException("Swagger文档中缺少version字段");
        }

        String projectName = info.getString("title");
        if (StringUtils.isEmpty(projectName)) {
            throw new BusinessException("Swagger文档中缺少title字段");
        }
        Project project = projectService.getByName(projectName);
        if (project == null) {
            throw new BusinessException("项目不存在");
        }

        String host = jsonObject.getString("host");
        if (StringUtils.isEmpty(host)) {
            throw new BusinessException("Swagger文档中缺少host字段");
        }

        Map<String, Long> groupNameToIdMap = new HashMap<>();
        JSONArray tags = jsonObject.getJSONArray("tags");
        if (tags != null && !tags.isEmpty()) {
            for (int i = 0; i < tags.size(); i++) {
                JSONObject tag = tags.getJSONObject(i);
                String groupName = tag.getString("name");
                Long groupId = groupService.add(project.getId(), groupName);
                groupNameToIdMap.put(groupName, groupId);
            }
        }

        JSONObject definitions = jsonObject.getJSONObject("definitions");
        List<InterfaceWithBLOBs> interfaces = new ArrayList<>();
        JSONObject paths = jsonObject.getJSONObject("paths");
        if (paths != null && !paths.isEmpty()) {
            for (String path : paths.keySet()) {
                JSONObject pathItem = paths.getJSONObject(path);
                JSONObject post = pathItem.getJSONObject("post");
                if (post != null && !post.isEmpty()) {
                    String groupName = post.getJSONArray("tags").getString(0);
                    String intefaceName = post.getString("summary");
                    String intefaceDesc = post.getString("description");

                    JSONArray parameters = post.getJSONArray("parameters");
                    String param = "";
                    if (parameters != null && parameters.size() == 1) {
                        JSONObject body = parameters.getJSONObject(0);
                        String in = body.getString("in");
                        if ("body".equals(in)) {
                            JSONObject schema = body.getJSONObject("schema");
                            param = schema.getString("$ref");
                            param = param.substring(param.lastIndexOf("/") + 1);
                            param = definitions.getString(param);
                        }
                    }

                    JSONObject responses = post.getJSONObject("responses");
                    String res = "";
                    if (responses != null && !responses.isEmpty()) {
                        JSONObject schema = responses.getJSONObject("200").getJSONObject("schema");
                        res = schema.getString("$ref");
                        res = res.substring(res.lastIndexOf("/") + 1);
                        res = definitions.getString(res);
                    }

                    interfaces.add(buildInterface(version, project.getId(), groupNameToIdMap.get(groupName), host, path, intefaceName, intefaceDesc, param, res));
                } else {
                    log.warn("host {} path {} 缺少post方法", host, path);
                }
            }
        }

        interfaceService.batchAdd(project.getId(), version, interfaces);

    }

    public InterfaceWithBLOBs buildInterface(String version, Long projectId, Long groupId, String host, String path, String intefaceName, String intefaceDesc, String param, String res) {
        InterfaceWithBLOBs anInterface = new InterfaceWithBLOBs();
        anInterface.setVersion(version);
        anInterface.setProjectId(projectId);
        anInterface.setGroupId(groupId);
        anInterface.setName(intefaceName);
        anInterface.setPath(path);
        anInterface.setDomain(host);
        anInterface.setDesc(intefaceDesc);
        anInterface.setParameters(param);
        anInterface.setResult(res);
        anInterface.setCreatetime(new Date());
        anInterface.setUpdatetime(new Date());
        return anInterface;
    }
}
